package com.wxb.plugin.core.gen;

import com.google.common.collect.Lists;
import org.apache.poi.xwpf.usermodel.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import static com.wxb.plugin.core.gen.InterfaceApiGen2.*;

/**
 * @author wxb
 * @createTime 2025/3/19 9:55
 */
public class GenWord {
    // 模板docx地址
    static String template = "interface2.docx";
    static String template_banner = "interface_banner2.docx";
    // docx模板
    static Template templateStyle = null;
    //表头
    static String[] tabHeader = {"序号", "中文名称", "英文名称", "类型", "必填", "说明"};

    public static String toFile(List<ControllerApiInfo> controllerApiInfos) {
        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(InterfaceApiGen2.class.getClassLoader().getResourceAsStream(template));
            XWPFDocument document_write = new XWPFDocument(InterfaceApiGen2.class.getClassLoader().getResourceAsStream(template_banner));
//            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(template));
            int size = document.getParagraphs().size();
            System.out.println("docx file size:" + size);
            //解析样式
            templateStyle = parseTemplate(document);
            //填充内容
            for (int i = 0; i < controllerApiInfos.size(); i++) {
                ControllerApiInfo info = controllerApiInfos.get(i);
                if (info.hide) {
                    continue;
                }
                // 设置一级标题
                addParagraph(document_write, info.note, 0);
                for (MethodApiInfo method : info.methodApiInfos) {
                    if (method.hide) {
                        continue;
                    }
                    fillMethodApi(document_write, method);
                }
            }

            // 删除模板
            for (int i = 0; i <= size; i++) {
                document.removeBodyElement(0);
            }
            File file = new File(out + docxPrefix + getTimeStamp() + ".docx");
            FileOutputStream stream = new FileOutputStream(file);
            document_write.write(stream);
            stream.close();
            document_write.close();
            document.close();
            System.out.println("file name :" + file.getName());
            System.out.println("generator file success！");
            return file.getPath();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out;
    }

    public static String getTimeStamp() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH-mm-ss");
        Date date = new Date();
        return sdf.format(date);
    }

    public static void fillMethodApi(XWPFDocument document, MethodApiInfo api) {
        if (api == null) {
            return;
        }
        // 设置一级标题
        addParagraph(document, api.title, 1);

        // 业务描述
        addParagraph(document, subHeader[0] + ": " + api.businessDesc, 2);

        // 接口提供方
        addParagraph(document, subHeader[1] + ": " + api.interfaceProvide, 2);

        // 接口地址
        addParagraph(document, subHeader[2] + ": ", 2);
        for (String u : api.url) {
            addParagraph(document, u, 3);
        }

        // 接口请求字段
        addEntityFields(document, api.paramEntities, subHeader[3], 2);
        // 接口响应字段
        addEntityFields(document, api.returnEntities, subHeader[4], 2);

        // 请求示例报文
        addParagraph(document, subHeader[5] + ": ", 2);
        addContent(document, api.requestExample, 3);

        // 响应示例报文
        addParagraph(document, subHeader[6] + ": ", 2);
        addContent(document, api.responseExample, 3);
    }

    public static void addEntityFields(XWPFDocument document, List<MethodApiInfo.FieldInfo> api, String text, int level) {
        // 接口请求字段
        addParagraph(document, text + ": ", level);
        if (api != null && !api.isEmpty()) {
            for (MethodApiInfo.FieldInfo entityInfo : api) {
                String info = StringUtil.isNotBlank(entityInfo.nameCn) ? "(" + entityInfo.nameCn + ")" : "";
                addParagraph(document, (entityInfo.requestType == null ? "" : entityInfo.requestType)
                        + "  "
                        + entityInfo.nameEn
                        + info
                        + ": ", 3);
                if (entityInfo instanceof MethodApiInfo.EntityInfo entity) {
                    addTable(document, entity.fieldInfos);
                } else {
                    addTable(document, Lists.newArrayList(entityInfo));
                }
            }
        }
    }

    public static void addContent(XWPFDocument document, String text, int level) {
        if (StringUtil.isNotBlank(text)) {
            for (String s : text.split("\n")) {
                addParagraph(document, s, level);
            }
        }
    }

    public static XWPFParagraph addParagraph(XWPFDocument document, String text, int level) {
        if (templateStyle == null) {
            System.out.println("模板为空");
        }
        XWPFParagraph paragraph = document.createParagraph();
        XWPFRun run = paragraph.createRun();
        run.setText(text);
        run.setFontFamily("宋体");
        switch (level) {
            case 0:
                paragraph.setStyle("2");
                paragraph.getCTP().setPPr(templateStyle.header1.gstyle);
                run.getCTR().setRPr(templateStyle.header1.rstyle);
                break;
            case 1:
                paragraph.setStyle("3");
                paragraph.getCTP().setPPr(templateStyle.headerSub1.gstyle);
                run.getCTR().setRPr(templateStyle.headerSub1.rstyle);
                break;
            case 2:
                paragraph.setStyle("11");
                paragraph.getCTP().setPPr(templateStyle.header2.gstyle);
                run.getCTR().setRPr(templateStyle.header2.rstyle);
                break;
            case 3:
            default:
                paragraph.setStyle("11");
                paragraph.getCTP().setPPr(templateStyle.header3.gstyle);
                run.getCTR().setRPr(templateStyle.header3.rstyle);
        }
        return paragraph;
    }


    public static void addTable(XWPFDocument document, List<MethodApiInfo.FieldInfo> fieldInfos) {
        if (fieldInfos != null && !fieldInfos.isEmpty()) {
            // 初始化表及其样式
            XWPFTable xwpfTable = document.insertNewTbl(document.createParagraph().getCTP().newCursor());
            xwpfTable.getCTTbl().setTblGrid(templateStyle.getTable().getTableStyle().getTblGrid());
            xwpfTable.getCTTbl().setTblPr(templateStyle.getTable().getTableStyle().getTblPr());
            // 初始化行列样式和行数列数
            styleTableAndSize(xwpfTable, fieldInfos.size() + 1, tabHeader.length);
            // 设置表头
            setTableHeader(xwpfTable);
            // 填充内容
            for (int i = 0; i < fieldInfos.size(); i++) {
                MethodApiInfo.FieldInfo fieldInfo = fieldInfos.get(i);
                XWPFTableRow row = xwpfTable.getRow(i + 1);
                XWPFTableCell cell0 = row.getCell(0);
                cell0.setText(String.valueOf(fieldInfo.serial));
                XWPFTableCell cell1 = row.getCell(1);
                cell1.setText(fieldInfo.nameCn);
                XWPFTableCell cell2 = row.getCell(2);
                cell2.setText(fieldInfo.nameEn);
                XWPFTableCell cell3 = row.getCell(3);
                cell3.setText(fieldInfo.type);
                XWPFTableCell cell4 = row.getCell(4);
                cell4.setText(String.valueOf(fieldInfo.isNecessary));
                XWPFTableCell cell5 = row.getCell(5);
                cell5.setText(fieldInfo.information);
            }
        }
    }

    public static void setTableHeader(XWPFTable xwpfTable) {
        XWPFTableRow row = xwpfTable.getRow(0);
        for (int i = 0; i < tabHeader.length; i++) {
            row.getCell(i).setText(tabHeader[i]);
        }
    }

    public static void styleTableAndSize(XWPFTable xwpfTable, int row, int cell) {
        for (int i = 0; i < row; i++) {
            XWPFTableRow row1 = i == 0 ? xwpfTable.getRow(0) : xwpfTable.createRow();
            if (i == 0) {
                row1.getCtRow()
                        .setTrPr(templateStyle.getTable().row);
                for (int i1 = 0; i1 < cell; i1++) {
                    XWPFTableCell cell1 = i1 == 0 ? row1.getCell(0) : row1.createCell();
                    cell1.getCTTc().setTcPr(templateStyle.getTable().cell);
                }
            }

        }
    }

    public static Template parseTemplate(XWPFDocument document) throws IOException {
        // 表格
        XWPFTable xwpfTable = document.getTables().get(0);
        Template.Table table = new Template.Table();
        table.tableStyle = xwpfTable.getCTTbl();
        table.row = xwpfTable.getRow(0).getCtRow().getTrPr();
        table.cell = xwpfTable.getRow(0).getCell(0).getCTTc().getTcPr();
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        //  标题
        Template.Header header1 = new Template.Header();
        header1.setGstyle(paragraphs.get(0).getCTP().getPPr());
        header1.setRstyle(paragraphs.get(0).getRuns().get(0).getCTR().getRPr());

        Template.Header headerSub1 = new Template.Header();
        headerSub1.setGstyle(paragraphs.get(1).getCTP().getPPr());
        headerSub1.setRstyle(paragraphs.get(1).getRuns().get(0).getCTR().getRPr());

        Template.Header header2 = new Template.Header();
        header2.setGstyle(paragraphs.get(2).getCTP().getPPr());
        header2.setRstyle(paragraphs.get(2).getRuns().get(0).getCTR().getRPr());
        Template.Header header3 = new Template.Header();
        header3.setGstyle(paragraphs.get(3).getCTP().getPPr());
        header3.setRstyle(paragraphs.get(3).getRuns().get(0).getCTR().getRPr());
        Template template1 = new Template(header1, header2, header3, table);
        template1.headerSub1 = headerSub1;
        return template1;
    }
}
